/**
 * A Slice is a length-prefixed pointer to contiguous values.
 *
 * Slice is used as the base for length-prefixed types such as Array and
 * String.
 */
struct Slice[T] {
    public var length: Size;
    public var data: Ptr[T];

    public function ref(): Ptr[T] {
        return this.data;
    }

    public function clear() {
        memset(this.data, 0, sizeof T * this.length);
    }

    // public function contains(value: T): Bool {
    //     for i in 0 ... this.length {
    //         if *(this.data + i) == value {
    //             return true;
    //         }
    //     }
    //     return false;
    // }

    rules {
        ($this[$i ... $j]) => struct Self {length: $j - $i, data: &$this.data[$i]};
        ($this[$i]) => $this.data[$i];
        ($this.unsafeLast) => $this[$this.length - 1];

        // optimize Slice iteration at compile time when the type is known
        (for $ident in $this {$e}) => {
            var __length = $this.length;
            for __i in 0 ... __length {
                var $ident = $this.data[__i];
                {$e}
            }
        }
    }
}
